package yl.hs.bmipfull.utils;

import yl.hs.bmipfull.annotations.DBField;
import yl.hs.bmipfull.utils.datastate.SearchFilterType;
import yl.hs.bmipfull.viewmodels.FilterFieldModel;
import yl.hs.bmipfull.viewmodels.QueryFilter;

import java.io.File;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * SearchFilterEngine
 * @category
 * @author 谢景广
 * @date 2021-10-22
 */
public class SearchFilterEngine {
    public static String getSearchFields(Class<?> classObject, List<ISearchFilter> filters){
        return "*";
    }

    public static List<FilterFieldModel> getFilterFields(Class<?> classObject){
       var fields = classObject.getDeclaredFields();
       List<FilterFieldModel> filterList = new ArrayList<FilterFieldModel>();
       for (var field : fields){
          var df = field.getAnnotation(DBField.class);
          if(df!=null && df.isSearch()){
              filterList.add(new FilterFieldModel(field.getName(),field.getType().getName(),df.disName()));
          }
       }
       return filterList;
    }

    public static List<Map<String,Object>> generateQueryList(List<QueryFilter> filters,Class<?> type){
        List<Map<String,Object>> list = new ArrayList<>();
        if(filters !=null && filters.size()>0) {
            for (int i = 0; i < filters.size(); i++) {
                var filter = filters.get(i);
                if (Tl.filedExists(type, filter.getField())) {
                    try {
                        var obj = new HashMap<String, Object>();
                        var field = Tl.getClassField(type, filter.getField());
                        var sfType = SearchFilterType.valueOf(filter.getOperator());
                        obj.put("field", getField(filter.getField(), sfType));
                        obj.put("value", getValue(filter.getSearchVal(), field, sfType));
                        list.add(obj);
                    } catch (Exception ee) {
                        ee.printStackTrace();
                    }
                }
            }
        }
        return list;
    }

    private static String getField(String field,SearchFilterType type){
        String st = switch (type) {
            case Equals -> "%s = ";
            case NoEqual -> "%s != ";
            case LessThan -> "%s < ";
            case GreaterThan -> "%s > ";
            case GreaterOrEqual -> "%s >= ";
            case LessOrEqual -> "%s <= ";
            case NoContains -> "%s not like ";
            case Contains, StartWith -> "%s like ";
            default -> "";
        };
        return String.format(st,field);
    }

    private static Object getValue(String value, Field field,SearchFilterType type) throws ParseException {
        Object s = value;
        switch (type){
            case Equals:
            case NoEqual:
            case LessThan:
            case GreaterThan:
            case GreaterOrEqual:
            case LessOrEqual:
                s = Tl.getFieldValue(value,field);
                break;
            case NoContains:
            case Contains:
                s = '%'+value+'%';
                break;
            case StartWith:
                s = '%'+value;
                break;
        }
        return  s;
    }
}
